package drds.plus.executor.cursor.cursor.impl;

import drds.plus.executor.cursor.cursor.Cursor;
import drds.plus.executor.record_codec.record.KeyValueRecordPair;
import drds.plus.executor.record_codec.record.Record;
import drds.plus.executor.row_values.RowValues;
import drds.plus.sql_process.abstract_syntax_tree.configuration.ColumnMetaData;
import drds.plus.util.GeneralUtil;
import drds.tools.Threads;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public abstract class AbstractCursor implements Cursor {
    public Cursor cursor;
    protected boolean inited = false;

    public AbstractCursor(Cursor cursor) {
        this.cursor = cursor;
    }

    protected void init() throws RuntimeException {
        inited = true;
    }

    protected void checkInited() throws RuntimeException {
        if (!inited) {
            throw new RuntimeException("not yet inited ");
        }
    }

    public Cursor getCursor() {
        throw new IllegalArgumentException("null object");
    }

    protected Cursor parentCursor() {
        return cursor;
    }

    public List<ColumnMetaData> parentCursorReturnColumnMetaDataList() throws RuntimeException {
        return this.cursor.getColumnMetaDataList();
    }

    public boolean isDone() {
        return cursor.isDone();
    }

    //
    public void put(Record key, Record value) throws RuntimeException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean delete() throws RuntimeException {
        throw new IllegalArgumentException("null object");
    }

    protected boolean parentCursorDelete() throws RuntimeException {
        return cursor.delete();
    }

    public List<RuntimeException> close(List<RuntimeException> exceptions) {
        List<RuntimeException> RuntimeExceptionList = parentCursorClose(exceptions);
        return RuntimeExceptionList;
    }

    protected List<RuntimeException> parentCursorClose(List<RuntimeException> RuntimeExceptionList) {
        if (cursor != null) {
            List<RuntimeException> ex = cursor.close(RuntimeExceptionList);
            cursor = null;
            return ex;
        }

        if (RuntimeExceptionList == null) {
            RuntimeExceptionList = new ArrayList<RuntimeException>();
        }
        return RuntimeExceptionList;

    }

    /**
     * 单个记录遍历
     */
    public void beforeFirst() throws RuntimeException {
        throw new IllegalArgumentException("null object");
    }

    protected void parentCursorBeforeFirst() throws RuntimeException {
        cursor.beforeFirst();
    }

    public RowValues first() throws RuntimeException {
        throw new IllegalArgumentException("null object");
    }

    protected RowValues parentCursorFirst() throws RuntimeException {
        return cursor.first();
    }

    public RowValues prev() throws RuntimeException {
        throw new IllegalArgumentException("null object");
    }

    protected RowValues parentCursorPrev() throws RuntimeException {
        return cursor.prev();
    }

    public RowValues next() throws RuntimeException {
        Threads.checkInterrupted();
        throw new IllegalArgumentException("null object");
    }

    protected RowValues parentCursorNext() throws RuntimeException {
        Threads.checkInterrupted();
        if (cursor == null) {
            return null;
        }
        return cursor.next();
    }

    public RowValues current() throws RuntimeException {
        throw new IllegalArgumentException("null object");
    }

    protected RowValues parentCursorCurrent() throws RuntimeException {
        return cursor.current();
    }

    public RowValues last() throws RuntimeException {
        throw new IllegalArgumentException("null object");
    }

    protected RowValues parentCursorLast() throws RuntimeException {
        return cursor.last();
    }

    /**
     * skip
     */
    public boolean skipTo(Record keyRecord) throws RuntimeException {
        throw new IllegalArgumentException("null object");
    }

    protected boolean parentCursorSkipTo(Record key) throws RuntimeException {
        return cursor.skipTo(key);
    }

    public boolean skipTo(KeyValueRecordPair keyKeyValueRecordPair) throws RuntimeException {
        throw new IllegalArgumentException("null object");
    }

    protected boolean parentCursorSkipTo(KeyValueRecordPair key) throws RuntimeException {
        return cursor.skipTo(key);
    }

    /**
     * 重复值处理
     */
    public RowValues getNextDuplicateValueRowData() throws RuntimeException {
        throw new IllegalArgumentException("null object");
    }

    protected RowValues parentCursorGetNextDuplicateRowData() throws RuntimeException {
        return cursor.getNextDuplicateValueRowData();
    }

    public Map<Record, DuplicateValueRowDataLinkedList> mgetRecordToDuplicateValueRowDataLinkedListMap(List<Record> keyRecordList, boolean prefixMatch, boolean keyFilterOrValueFilter) throws RuntimeException {
        throw new IllegalArgumentException("null object");
    }

    protected Map<Record, DuplicateValueRowDataLinkedList> parentCursorMgetRecordToDuplicateValueRowDataLinkedListMap(List<Record> keys, boolean prefixMatch, boolean keyFilterOrValueFilter) throws RuntimeException {
        return cursor.mgetRecordToDuplicateValueRowDataLinkedListMap(keys, prefixMatch, keyFilterOrValueFilter);
    }

    public List<DuplicateValueRowDataLinkedList> mgetDuplicateValueRowDataLinkedListList(List<Record> keyRecordList, boolean prefixMatch, boolean keyFilterOrValueFilter) throws RuntimeException {
        throw new IllegalArgumentException("null object");
    }

    protected List<DuplicateValueRowDataLinkedList> parentCursorMgetDuplicateValueLinkedListList(List<Record> keys, boolean prefixMatch, boolean keyFilterOrValueFilter) throws RuntimeException {
        return cursor.mgetDuplicateValueRowDataLinkedListList(keys, prefixMatch, keyFilterOrValueFilter);
    }

    //
    public String toStringWithInden(int inden) {
        StringBuilder sb = new StringBuilder();
        String tabTittle = GeneralUtil.getTab(inden);
        GeneralUtil.printlnToStringBuilder(sb, tabTittle + "abstract cursor");
        return sb.toString();
    }

    public String toString() {
        return toStringWithInden(0);
    }

}
